<script setup lang="ts">
import {onMounted, ref,} from 'vue'


const videoA = ref<HTMLVideoElement>() as any
const videoB = ref<HTMLVideoElement>() as any

let list = ref([])
let id = ref('')

let receiveId = ref('')

const getNewStream = async () => {
  let stream = new MediaStream()

  let video_stm = await navigator.mediaDevices.getUserMedia({
    video:true
  })

  let audio_stm = await navigator.mediaDevices.getUserMedia({
    audio:true
  })

  video_stm.getVideoTracks().map(row => stream.addTrack(row))
  audio_stm.getVideoTracks().map(row => stream.addTrack(row))
  
  videoA.value.srcObject  = stream
  
  return stream
}

async function init(){
  let stream = await getNewStream()
  
  // peerInit(stream)
}


const peerInit = async (stream:any) => {
  // 1. 创建连接实例
  let peerA = new RTCPeerConnection()
  let peerB = new RTCPeerConnection()
  // 2. 添加视频流轨道
  stream.getTracks().forEach((track:any) => {
    peerA.addTrack(track, stream)
  })
  // 添加 candidate
  peerA.onicecandidate = event => {
    if (event.candidate) {
      peerB.addIceCandidate(event.candidate)
    }
  }
  // 检测连接状态
  peerA.onconnectionstatechange = () => {
    if (peerA.connectionState === 'connected') {
      console.log('对等连接成功！')
    }
  }
  // 监听数据传来
  peerB.ontrack = async event => {
    const [remoteStream] = event.streams
    videoB.value.srcObject = remoteStream
  }
  // 互换sdp认证
  transSDP(peerA,peerB)
}
// 互换SDP
const transSDP = async (peerA:any,peerB:any) => {
  // 1. 创建 offer
  let offer = await peerA.createOffer()
  await peerB.setRemoteDescription(offer)
  // 2. 创建 answer
  let answer = await peerB.createAnswer()
  await peerB.setLocalDescription(answer)
  // 3. 发送端设置 SDP
  await peerA.setLocalDescription(offer)
  await peerA.setRemoteDescription(answer)
}



onMounted(() => {
  // init()
})

var peerA = new RTCPeerConnection()
var peerB = new RTCPeerConnection()


  // 检测连接状态
  peerA.onconnectionstatechange = () => {
    if (peerA.connectionState === 'connected') {
      console.log('对等连接成功！')
    }
  }
  // 监听数据传来
  peerB.ontrack = async event => {
    const [remoteStream] = event.streams
    videoB.value.srcObject = remoteStream
  }

let offer = null as any
let answer = null as any

let socket = new WebSocket('ws://localhost:8080')

socket.onopen = function(event) {
  console.log('开启连接');
     
}

socket.onclose = function(event) {
    console.log('连接关闭',event);
}

socket.onmessage = async function(event) {
  console.log(parse(event.data));

  let data = parse(event.data) as any
  if (typeof(data) === 'object'){
    switch(data.type){
      case 'list':
        list.value = data.data;
        break;
      case 'offer':
        console.log('offer');
        
        offer = data.data.offer
        await peerB.setRemoteDescription(offer)

        answer = await peerB.createAnswer()
        await peerB.setLocalDescription(answer)

        if (id.value){
          console.log(offer,answer);
          await peerA.setLocalDescription(offer)
          await peerA.setRemoteDescription(answer)
        } else {
          receiveId.value = data.data.id
          receiveColor.value = 'red'
        }
        break;
      case 'answer':
        console.log('answer');
        answer = data.data.answer
        await peerA.setLocalDescription(offer)
        await peerA.setRemoteDescription(answer)
        break;

      case 'candidate':
        let candidate = data.data.candidate
        console.log('candidate',candidate);
        
        peerB.addIceCandidate(candidate)
        break;
      default:
        break;
    }
  }
}

function parse(data:any){
  let res = ''
  try {
    res = JSON.parse(data)
  } catch (error) {
    res = data
  }
  return res
 }



const send = async () => {
  let idNum = id.value || receiveId.value
  console.log('id'+id.value,'reid'+receiveId.value);
  
  let stream = await getNewStream()
  // 2. 添加视频流轨道
  stream.getTracks().forEach((track:any) => {
    peerA.addTrack(track, stream)
  })
  // 添加 candidate
  peerA.onicecandidate = event => {
    if (event.candidate) {
      socket.send(JSON.stringify({type:'candidate',data:{id:idNum, candidate:event.candidate}}))
      // peerB.addIceCandidate(event.candidate)
    }
  }

  offer = await peerA.createOffer()

  socket.send(JSON.stringify({type:'offer',data:{id:idNum,offer}}))
  


  // if(socket.readyState === WebSocket.OPEN){
  //   socket.send('拨打')
  // }

}


const receive = async () => {
  if (id.value) return
  let stream = await getNewStream()
  // 2. 添加视频流轨道
  stream.getTracks().forEach((track:any) => {
    peerA.addTrack(track, stream)
  })

  socket.send(JSON.stringify({type:'answer',data:{id:receiveId.value,answer}}))
}

const choose = (data) => {
  id.value = data
}


let receiveColor = ref('black')

</script>

<template>
  <div class="chat">
    <div class="socket">
      <h3>用户列表</h3>
      <ul v-for=" item in list">
        <li @click="choose(item)">{{ item }}</li>
      </ul>
    </div>
    <div class="client left">
      <h1>chatA</h1>
      <video ref="videoA" autoplay></video>
      <button @click="send()">拨打</button>
    </div>
    <div class="client right">
      <h1>chatB</h1>
      <video ref="videoB" autoplay></video>
      <button @click="receive" :style="{color:receiveColor}">接听</button>
    </div>
  </div>
</template>

<style scoped>
.chat{
  display: flex;
  background-color: rgba(128, 128, 128, 0.274);
}
.client{
  display: flex;
  flex-direction: column;
  align-items: center;
}
.client button{
  width: max-content;
}
</style>
